package cn.com.surker.control.controller;

import cn.com.surker.base.BaseEntity;
import cn.com.surker.base.ExportInter;
import cn.com.surker.common.Code;
import cn.com.surker.control.entity.ControlExpend;
import cn.com.surker.control.entity.ControlExpendBatch;
import cn.com.surker.control.entity.ControlInvoice;
import cn.com.surker.control.entity.vo.ControlExpendBatchVo;
import cn.com.surker.control.service.ErpControlExpendBatchService;
import cn.com.surker.control.service.ErpControlExpendService;
import cn.com.surker.control.service.ErpControlInvoiceService;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.production.invoice.InvoiceCreateTypeEnum;
import cn.com.surker.enums.production.invoice.InvoiceProcessEnum;
import cn.com.surker.excel.ExcelCell;
import cn.com.surker.excel.ExcelReportUtils;
import cn.com.surker.handler.BCSStarter;
import cn.com.surker.lab.entity.LabExpend;
import cn.com.surker.lab.entity.LabExpendBatch;
import cn.com.surker.lab.service.LabExpendBatchService;
import cn.com.surker.lab.service.LabExpendService;
import cn.com.surker.production.controller.ProBaseController;
import cn.com.surker.production.entity.ProductionIndent;
import cn.com.surker.production.entity.ProductionInvoice;
import cn.com.surker.production.entity.TranCar;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.model.CacheUser;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.transaction.RollbackException;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 工控发货单数据
 *
 * @author luotao
 * @date 2025/1/6
 */
@RestController
@RequestMapping("/control/invoice")
public class ControlInvoiceController extends ProBaseController {

	@Autowired
	private BCSStarter bcsStarter;
	@Autowired
	private ErpControlInvoiceService erpControlInvoiceService;
	@Autowired
	private ErpControlExpendBatchService erpControlExpendBatchService;


	/**
	 * 查询工控机发货单
	 *
	 * @param startTime
	 * @param endTime
	 * @param site
	 * @param conAuto
	 * @param pageIndex
	 * @param limit
	 * @return
	 */
	@RequestMapping(value = "/page", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto page(String startTime, String endTime, String site, Integer conAuto, Integer linkErp, Integer pageIndex, Integer limit) {
		if (pageIndex == null) {
			pageIndex = 0;
		}
		if (limit == null) {
			limit = 50;
		}
		IPage<ControlInvoice> page = erpControlInvoiceService.findPage(startTime, endTime, site, conAuto, linkErp, pageIndex, limit);
		return RestResultDto.success(page);
	}

	/**
	 * 工控机数据新增到erp(根据任务单创建)
	 *
	 * @param controlInvId
	 * @param indentId
	 * @param sendStere
	 * @param proTime
	 * @param isAdd
	 * @param dispatcher
	 * @param mixUser
	 * @param dispatcherName
	 * @param mixUserName
	 * @param carId
	 * @param driver
	 * @param calcTranStere
	 * @param receiptType
	 * @param specialClearType
	 * @param roadType
	 * @param remark
	 * @param tranRemark
	 * @param pumpRemark
	 * @return
	 */
	@RequestMapping(value = "/add/{controlInvId}", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto addInvoice(@PathVariable Long controlInvId, Long indentId, Double sendStere, @DateTimeFormat(pattern = DateUtil.DATE_DETAIL_FORMATTER) Date proTime, Integer isAdd,
									Long dispatcher, Long mixUser, String dispatcherName, String mixUserName, Long carId, String driver, Integer calcTranStere, Integer receiptType, Integer specialClearType,
									Integer roadType, String remark, String tranRemark, String pumpRemark) {
		if (controlInvId == null) {
			return RestResultDto.fail("请选择工控机发货单");
		}
		if (indentId == null) {
			return RestResultDto.fail("请选择任务单");
		}
		if (sendStere == null || sendStere < 0) {
			return RestResultDto.fail("请输入正确的发货方量");
		}
		if (proTime == null) {
			return RestResultDto.fail("请选择生产时间");
		}
		if (isAdd == null) {
			return RestResultDto.fail("请选择是否累计");
		}
		if (dispatcher == null) {
			return RestResultDto.fail("请选择调度员");
		}
		if (mixUser == null) {
			return RestResultDto.fail("请选择拌台操作员");
		}
		if (carId == null) {
			return RestResultDto.fail("请选择运输车辆");
		}
		if (StringUtils.isBlank(driver)) {
			return RestResultDto.fail("请选择司机");
		}
		//	查询工控机发货单数据
		ControlInvoice controlInvoice = erpControlInvoiceService.getById(controlInvId);
		if (!BaseEntity.validateExist(controlInvoice)) {
			return RestResultDto.fail("ERP上的工控机发货单数据不存在或者已删除");
		}
		Integer conAuto = controlInvoice.getConAuto();
		if (conAuto == null || !conAuto.equals(1)) {
			return RestResultDto.fail("该工控机发货单不是自行生产的,不允许关联");
		}
		Integer linkErp = controlInvoice.getLinkErp();
		if (linkErp != null && linkErp.equals(1)) {
			return RestResultDto.fail("该工控机发货单已经关联erp发货单,不允许重复操作");
		}
		//	查询任务单
		ProductionIndent productionIndent = indentService.getById(indentId);
		if (!BaseEntity.validateExist(productionIndent)) {
			return RestResultDto.fail("未查询出任务单数据,请选择正确的任务单");
		}
		TranCar tranCar = tranCarService.getById(carId);
		if (tranCar == null) {
			return RestResultDto.fail("该运输车辆不存在,请重新选择正确的车辆");
		}
		CacheUser user = getUser();
		String userName = user.getName();
		//	创建发货单数据
		ProductionInvoice invoice = new ProductionInvoice();
		//	设置默认信息
		invoice.setOrgId(orgId);
		// invoice.setCode(ProductionInvoice.initCode(orgCode));
		invoice.initCode(orgCode);
		invoice.setCreateType(InvoiceCreateTypeEnum.CON_MOVEMENT_LINK.getCode());
		invoice.setDistance(productionIndent.getDistance());
		invoice.setMixId(controlInvoice.getLineId());
		//	设置前端传入的信息
		invoice.setIndentId(indentId);
		invoice.setSendStere(sendStere);
		invoice.setProTime(proTime);
		invoice.setDispatcher(dispatcher);
		invoice.setDispatcherName(dispatcherName);
		invoice.setMixUser(mixUser);
		invoice.setMixUserName(mixUserName);
		invoice.setCarId(carId);
		invoice.setDriver(driver);
		invoice.setCalcTranStere(calcTranStere);
		invoice.setReceiptType(receiptType);
		invoice.setSpecialClearType(specialClearType);
		invoice.setRoadType(roadType);
		invoice.setRemark(remark);
		invoice.setTranRemark(tranRemark);
		invoice.setPumpRemark(pumpRemark);
		//	设置工控机id
		invoice.setControlInvoiceId(controlInvId);
		invoice.setCreator(userName);
		invoice.setCreateTime(new Date());
		invoice.setControlRemark("工控机发货单关联任务单创建的发货单");
		//	保存数据
		invoiceService.save(invoice);
		//	发货单id
		Long invoiceId = invoice.getId();
		bcsStarter.linkConInv2Erp(invoiceId, controlInvoice);
		return RestResultDto.success();
	}

	/**
	 * 工控发货单绑定erp发货单
	 *
	 * @param erpControlId 工控机发货单
	 * @param erpInvoiceId erp发货单
	 * @return
	 */
	@RequestMapping(value = "/link", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto linkInvoice(Long erpControlId, Long erpInvoiceId) {
		if (erpControlId == null || erpInvoiceId == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY);
		}
		//	查询erp发货单
		ControlInvoice controlInvoice = erpControlInvoiceService.getById(erpControlId);
		if (!BaseEntity.validateExist(controlInvoice)) {
			return RestResultDto.fail("工控机发货单不存在");
		}
		Integer conAuto = controlInvoice.getConAuto();
		if (conAuto == null || !conAuto.equals(1)) {
			return RestResultDto.fail("该工控机发货单不为自主生产,不允许操作");
		}
		Integer linkErp = controlInvoice.getLinkErp();
		if (linkErp != null && linkErp.equals(1)) {
			return RestResultDto.fail("该工控机发货单已经关联ERP");
		}
		ProductionInvoice proInvoice = invoiceService.getById(erpInvoiceId);
		if (!BaseEntity.validateExist(proInvoice)) {
			return RestResultDto.fail("ERP发货单不存在");
		}
		Integer createType = proInvoice.getCreateType();
		Integer process = proInvoice.getProcess();
		if (!InvoiceCreateTypeEnum.MOVEMENT.getCode().equals(createType)
			// && !InvoiceCreateTypeEnum.CON_MOVEMENT_AUTO.getCode().equals(createType)
			&& !InvoiceCreateTypeEnum.CON_MOVEMENT_LINK.getCode().equals(createType)
			&& !InvoiceProcessEnum.WORK_ORDER_1.getCode().equals(process)) {
			return RestResultDto.fail("该ERP发货单不为手动票,不允许操作");
		}
		Long controlInvoiceId = proInvoice.getControlInvoiceId();
		if (controlInvoiceId != null) {
			return RestResultDto.fail("该ERP发货单已经关联数据,不允许操作");
		}
		Date proTime = controlInvoice.getProTime();
		//	更新发货单信息
		proInvoice.setControlInvoiceId(erpControlId);
		proInvoice.setProcess(InvoiceProcessEnum.TRAN_COMPLETE.getCode());
		proInvoice.setProTime(proTime);
		//	更改关联状态
		proInvoice.setCreateType(InvoiceCreateTypeEnum.CON_MOVEMENT_LINK.getCode());
		proInvoice.setControlRemark("手动票关联工控机发货单");
		invoiceService.updateById(proInvoice);
		//	发货单id
		Long invoiceId = proInvoice.getId();
		bcsStarter.linkConInv2Erp(invoiceId, controlInvoice);
		return RestResultDto.success();
	}

	@RequestMapping(value = "/erp/invoice/{controlInvId}", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto erpInvoice(@PathVariable Long controlInvId) {
		if (controlInvId == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY);
		}
		//	查询工控机发货单数据
		ControlInvoice controlInvoice = erpControlInvoiceService.getById(controlInvId);
		if (!BaseEntity.validateExist(controlInvoice)) {
			return RestResultDto.fail("未查询到工控机发货单数据");
		}
		//	查询发货单信息
		QueryWrapper<ProductionInvoice> qw = new QueryWrapper<>();
		qw.eq("status", StateEnum.ENABLED.getCode());
		qw.eq("control_invoice_id", controlInvId);
		qw.eq("org_id", orgId);
		qw.last("limit 1");
		ProductionInvoice erpInvoice = invoiceService.getOne(qw);
		if (erpInvoice == null) {
			return RestResultDto.fail("未查询到关联的发货单信息");
		}
		Long invoiceId = erpInvoice.getId();
		return RestResultDto.success(invoiceId);
	}

	/**
	 * 查询工控机的消耗
	 *
	 * @param conInvId
	 * @return
	 */
	@RequestMapping(value = "/expend/{conInvId}", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto expend(@PathVariable Long conInvId) {
		if (conInvId == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY);
		}
		List<ControlExpendBatchVo> expendBatchVoList = erpControlExpendBatchService.findDetailList(erpDb, conInvId);
		return RestResultDto.success(expendBatchVoList);
	}

	@RequestMapping(value = "/queryByErp/{erpInvId}", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto queryByErp(@PathVariable Long erpInvId) {
		if (erpInvId == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY);
		}
		//	查询发货单数据
		ProductionInvoice invoice = invoiceService.getById(erpInvId);
		if (invoice == null) {
			return RestResultDto.fail("未查询出工控机数据");
		}
		Long controlInvoiceId = invoice.getControlInvoiceId();
		if (controlInvoiceId == null) {
			return RestResultDto.fail("该发货单未关联工控机发货单");
		}
		ControlInvoice controlInvoice = erpControlInvoiceService.getById(controlInvoiceId);
		if (controlInvoice == null) {
			return RestResultDto.fail("未查询出工控机发货单");
		}
		return RestResultDto.success(controlInvoice);
	}

	@RequestMapping(value = "/sync", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto sync() {
		bcsStarter.syncControlInvoice();
		return RestResultDto.success();
	}

	/**
	 * 全量同步备份工控机发货单
	 * 同步数据步骤为:
	 * 1.全量同步工控机发货单
	 * 2.查询发货单下的盘和工控机的盘是否一致
	 * 3.匹配消耗
	 *
	 * @return
	 */
	@RequestMapping(value = "/sync/all", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto sync2(String startTime, String endTime) {
		if (!isAdmin()) {
			return RestResultDto.fail(Code.NO_PURVIEW);
		}
		if (StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)) {
			return RestResultDto.fail("请选择时间点");
		}
		bcsStarter.syncAllControl(startTime, endTime);
		return RestResultDto.success();
	}

	/**
	 * 导出数据
	 *
	 * @return
	 */
	@RequestMapping(value = "/export", method = RequestMethod.POST)
	@ResponseBody
	public void export(String startTime, String endTime, Integer conAuto, Integer linkErp, HttpServletResponse response) {
		if (StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)) {
			return;
		}
		//	查询数据
		List<ControlInvoice> controlInvoiceList = erpControlInvoiceService.findList(startTime, endTime, conAuto, linkErp);
		if (controlInvoiceList == null || controlInvoiceList.isEmpty()) {
			//	没有数据
			return;
		}
		CacheUser user = getUser();
		String userName = user.getName();
		XSSFWorkbook hw = new XSSFWorkbook();
		hw = exportTotalReport("工控发货单数据(" + startTime.split("\\s+")[0] + "~" + endTime.split("\\s+")[0] + ")", "制表人" + userName + ",导出时间:" + DateUtil.convertString(new Date()), controlInvoiceList, hw);
		OutputStream os = null;
		try {
			//响应到客户端
			if (orgId == 3l) {
				//	如果是雅博
				this.setResponseHeader(response, "gong_kong_fa_huo_shu_ju.xlsx");
			} else {
				this.setResponseHeader(response, "工控发货单数据.xlsx");
			}
			os = response.getOutputStream();
			hw.write(os);
			os.flush();
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
